﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Xsl;
using System.IO;
using System.Configuration;

public class XmlRenderer
{
    public static string Transform(string xmlString)
    {
        // dockbook.xsl has a DTD which is currently parsed
        // however it relies on ..\common\l10n.xml which also has a DTD, and this is not currently parsed

        //string xmlString = "<?xml version='1.0' encoding='utf-8'?><article xmlns='http://docbook.org/ns/docbook' version='5.0' xml:lang='en'><title>Sample article</title><para>This is a very short article.</para></article>";
        //string htmlFile = @"C:\xml\myarticle.html";

        //string xsltPath = @"C:\Users\Slava.Barouline\Documents\Visual Studio 2010\Projects\parl2\XmlRenderer\html\docbook.xsl";
        string xsltPath = ConfigurationManager.AppSettings["DocBookXslRootFolder"] + @"\html\docbook.xsl";
        
        var renderer = new XmlRenderer();
        
        string output = renderer.TransformXmlStringToString(xsltPath, xmlString);

        return output;
    }

    public void TransformXmlStringToFile(string xsltPath, string xmlString, string htmlFile)
    {
        // Create a stream from the input xml string
        XmlReader inputXml = ConvertXmlStringToStream(xmlString);

        // Set up a stream for the output html
        XmlWriter outputHtml = SetUpHtmlOutputFileStream(htmlFile);

        XslCompiledTransform xslt = new XslCompiledTransform();

        // Load the style sheet.
        XmlReader reader = SetupReaderForStylesheet(xsltPath);
        XsltSettings xsltSettings = SetTransformationProperties();
        XmlUrlResolver resolver = CreateDefaultResolver();

        xslt.Load(reader, xsltSettings, resolver);

        // Perform the transformation
        xslt.Transform(inputXml, outputHtml);
    }


    public string TransformXmlStringToString(string xsltPath, string xmlString)
    {
        // Create a stream from the input xml string
        XmlReader inputXml = ConvertXmlStringToStream(xmlString);

        // Set up a stream for the output html
        StringBuilder output = new StringBuilder();
        XmlWriter outputHtml = SetUpHtmlOutputStringStream(output);

        XslCompiledTransform xslt = new XslCompiledTransform();

        // Load the style sheet.
        XmlReader reader = SetupReaderForStylesheet(xsltPath);
        XsltSettings xsltSettings = SetTransformationProperties();
        XmlUrlResolver resolver = CreateDefaultResolver();

        xslt.Load(reader, xsltSettings, resolver);

        // Perform the transformation
        xslt.Transform(inputXml, outputHtml);

        return output.ToString();
    }
    private static XsltSettings SetTransformationProperties()
    {
        XsltSettings xsltSettings = new XsltSettings();
        xsltSettings.EnableDocumentFunction = true;
        xsltSettings.EnableScript = false;
        return xsltSettings;
    }

    private static XmlReader SetupReaderForStylesheet(string xsltPath)
    {
        XmlReaderSettings readerSettings = new XmlReaderSettings();
        readerSettings.DtdProcessing = DtdProcessing.Parse;

        var uri = Path.Combine(System.Reflection.Assembly.GetExecutingAssembly().CodeBase, "..", "..", xsltPath);
        XmlReader reader = XmlTextReader.Create(uri, readerSettings);
        return reader;
    }

    private XmlWriter SetUpHtmlOutputFileStream(string htmlFile)
    {
        XmlWriterSettings writerSettings = new XmlWriterSettings();
        writerSettings.Indent = true;
        writerSettings.IndentChars = "\t";
        writerSettings.ConformanceLevel = ConformanceLevel.Auto;
        XmlWriter outputHtml = XmlWriter.Create(htmlFile, writerSettings);
        return outputHtml;

    }

    private static XmlWriter SetUpHtmlOutputStringStream(StringBuilder output)
    {
        XmlWriterSettings writerSettings = new XmlWriterSettings();
        writerSettings.Indent = true;
        writerSettings.IndentChars = "\t";
        writerSettings.ConformanceLevel = ConformanceLevel.Auto;
        XmlWriter outputHtml = XmlWriter.Create(output, writerSettings);
        return outputHtml;
    }

    private static XmlReader ConvertXmlStringToStream(string xmlString)
    {
        StringReader strReader = new StringReader(xmlString);
        XmlReader inputXml = XmlTextReader.Create(strReader);
        return inputXml;
    }

    private static XmlUrlResolver CreateDefaultResolver()
    {
        XmlUrlResolver resolver = new XmlUrlResolver();
        resolver.Credentials = System.Net.CredentialCache.DefaultCredentials;
        return resolver;
    }
}
    
    
